<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>范围限定的聚合 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/_scoping_aggregations.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/_scoping_aggregations.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_scoping_aggregations.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/_scoping_aggregations.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="aggregations.html">聚合</a></span>
»
<span class="breadcrumb-node">范围限定的聚合</span>
</div>
<div class="navheader">
<span class="prev">
<a href="_the_sky_8217_s_the_limit.html">« 潜力无穷</a>
</span>
<span class="next">
<a href="_filtering_queries_and_aggregations.html">过滤和聚合 »</a>
</span>
</div>
<div class="chapter">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="_scoping_aggregations"></a>范围限定的聚合 (Scoping Aggregations)<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/300_Aggregations/40_scope.asciidoc">edit</a>
</h2>
</div></div></div>
<p>所有聚合的例子到目前为止，你可能已经注意到，我们的搜索请求省略了一个 <code class="literal">query</code> 。 整个请求只不过是一个聚合。</p>
<p>聚合可以与搜索请求同时执行，但是我们需要理解一个新概念： <em>范围 (scope)</em> 。 默认情况下，聚合与查询是对同一范围进行操作的，也就是说，聚合是基于查询时匹配到的文档的集合进行计算的。</p>
<p>让我们看看第一个聚合的示例：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/300_Aggregations/40_scope.json"></div>
<p>可以看到聚合是隔离的(<code class="word">in isolation</code>)。现实中，Elasticsearch 认为 "没有指定查询" 和 "查询所有文档" 是等价的。前面这个查询内部会转化成下面的这个请求：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /cars/transactions/_search
{
    "size" : 0,
    "query" : {
        "match_all" : {}
    },
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/300_Aggregations/40_scope.json"></div>
<p>因为聚合总是对查询范围内的结果进行操作的，所以一个隔离的聚合实际上是在对  <code class="literal">match_all</code> 的结果范围操作，即所有的文档。</p>
<p>一旦有了范围的概念，我们就能更进一步对聚合进行自定义。我们前面所有的示例都是对 <em>所有</em> 数据计算统计信息的：销量最高的汽车，所有汽车的平均售价，最佳销售月份等等。</p>
<p>利用范围，我们可以问类似“福特在售车有多少种颜色？”这样的问题。可以简单的在请求中加上一个查询（本例中为 <code class="literal">match</code> 查询）：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /cars/transactions/_search
{
    "query" : {
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : {
        "colors" : {
            "terms" : {
              "field" : "color"
            }
        }
    }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/300_Aggregations/40_scope.json"></div>
<p>因为我们没有指定 <code class="literal">"size" : 0</code> ，所以搜索结果和聚合结果都被返回了：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">{
...
   "hits": {
      "total": 2,
      "max_score": 1.6931472,
      "hits": [
         {
            "_source": {
               "price": 25000,
               "color": "blue",
               "make": "ford",
               "sold": "2014-02-12"
            }
         },
         {
            "_source": {
               "price": 30000,
               "color": "green",
               "make": "ford",
               "sold": "2014-05-18"
            }
         }
      ]
   },
   "aggregations": {
      "colors": {
         "buckets": [
            {
               "key": "blue",
               "doc_count": 1
            },
            {
               "key": "green",
               "doc_count": 1
            }
         ]
      }
   }
}</pre>
</div>
<p>看上去这并没有什么，但却对高大上的仪表盘来说至关重要。
加入一个搜索栏可以将任何静态的仪表板变成一个实时数据搜索设备。 这让用户可以搜索数据，查看所有实时更新的图形（由于ES提供了聚合和范围查询）。
这是 Hadoop 无法做到的！</p>
<h3>
<a id="_全局桶"></a>全局桶 (Global Bucket)<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/300_Aggregations/40_scope.asciidoc">edit</a>
</h3>
<p>通常我们希望聚合是在查询范围内的，但有时我们也想要搜索它的子集，而聚合的对象却是 <em>所有</em> 数据。</p>

<p>例如，比方说我们想知道福特汽车与 <em>所有</em> 汽车平均售价的比较。我们可以用普通的聚合（查询范围内的）得到第一个信息，然后用 <code class="literal">全局</code>  桶获得第二个信息。</p>

<p><code class="literal">全局</code> 桶包含 <em>所有</em> 的文档，它无视查询的范围。因为它还是一个桶，我们可以像平时一样将聚合嵌套在内：</p>
<div class="pre_wrapper lang-sense">
<pre class="programlisting prettyprint lang-sense">GET /cars/transactions/_search
{
    "size" : 0,
    "query" : {
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : {
        "single_avg_price": {
            "avg" : { "field" : "price" } <a id="CO196-1"></a><i class="conum" data-value="1"></i>
        },
        "all": {
            "global" : {}, <a id="CO196-2"></a><i class="conum" data-value="2"></i>
            "aggs" : {
                "avg_price": {
                    "avg" : { "field" : "price" } <a id="CO196-3"></a><i class="conum" data-value="3"></i>
                }

            }
        }
    }
}</pre>
</div>
<div class="sense_widget" data-snippet="snippets/300_Aggregations/40_scope.json"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO196-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>聚合操作在查询范围内. 本例中所有文档的品牌(make字段)必须匹配<code class="word">ford</code></p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO196-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">global</code> 全局桶没有参数。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO196-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>聚合操作针对所有文档，忽略汽车品牌。</p>
</td>
</tr>
</table>
</div>
<p><code class="word">single_avg_price</code> 度量计算是基于查询范围内所有文档，即所有 <code class="word">ford</code> 汽车。<code class="word">avg_price</code> 度量是嵌套在 <code class="literal">全局</code> 桶下的，这意味着它完全忽略了范围并对所有文档进行计算。聚合返回的平均值是所有汽车的平均售价。</p>
<p>如果能一直坚持读到这里，应该知道我们有个真言：尽可能的使用过滤器。它同样可以应用于聚合，在下一章中，我们会展示如何对聚合结果进行过滤而不是仅对查询范围做限定。</p>
</div>
<div class="navfooter">
<span class="prev">
<a href="_the_sky_8217_s_the_limit.html">« 潜力无穷</a>
</span>
<span class="next">
<a href="_filtering_queries_and_aggregations.html">过滤和聚合 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>